﻿using Microsoft.AspNetCore.Mvc;
using NetCore.Dtos;
using NetCore.Entities;
using NetCore.Services;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;

namespace NetCore.Controllers
{
    /// <summary>
    /// 泛型基类Controller，用于DevExtreme的CRUD
    /// </summary>
    /// <typeparam name="TEntity">实体</typeparam>
    ///  <typeparam name="TPrimaryKey">实体主键类型</typeparam>
    public abstract class BaseEntityController<TEntity, TPrimaryKey> : NetCoreControllerBase where TEntity : BaseEntity<TPrimaryKey>
    {
        protected IBaseNetCoreAppService<TEntity, TPrimaryKey> BaseService;

        protected BaseEntityController(IBaseNetCoreAppService<TEntity, TPrimaryKey> baseService)
        {
            BaseService = baseService;
        }

        #region 实体增删改查
        /// <summary>
        /// 根据主键获取实体
        /// </summary>
        /// <param name="key">实体主键</param>
        /// <returns></returns>
        public TEntity Get(TPrimaryKey key)
        {
            return BaseService.Get(new InputIdDto<TPrimaryKey> { Id = key });
            //return Json(entity);

            //BaseService.GetBaseRepository().UnitOfWorkManager.Current.Options
            //UnitOfWorkManager.Current.SetFilterParameter()
            //UnitOfWorkManager.Begin();
            //CurrentUnitOfWork.Completed+=
            //UnitOfWorkManager.Begin().CompleteAsync()
            //CurrentUnitOfWork.SaveChanges();

        }
        /// <summary>
        /// 添加实体
        /// </summary>
        /// <returns></returns>
        [HttpPost, Description("添加实体")]
        public async Task<IActionResult> Insert()
        {
            var entity = GetValues<TEntity>();
            return await Insert(entity);
        }
        /// <summary>
        /// 添加实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        [HttpPost, Description("添加实体")]
        public async Task<IActionResult> Insert(TEntity entity)
        {
            return DJson(await BaseService.GetBaseRepository().InsertAsync(entity));
        }
        /// <summary>
        /// 批量添加实体
        /// </summary>
        /// <param name="entities">实体集</param>
        /// <returns></returns>
        [HttpPost, Description("批量添加数据")]
        public async Task<IActionResult> BulkInsertAsync(List<TEntity> entities)
        {
            await BaseService.GetBaseRepository().BulkInsertAsync(entities);
            return SJson();
        }
        /// <summary>
        /// 修改实体
        /// </summary>
        /// <returns></returns>
        [HttpPut, Description("修改实体")]
        public virtual IActionResult Update()
        {
            var key = (TPrimaryKey)Convert.ChangeType(GetKeyString(), typeof(TPrimaryKey));//GetKey();
            var entity = BaseService.Get(new InputIdDto<TPrimaryKey> { Id = key });
            JsonConvert.PopulateObject(GetValuesString(), entity);
            entity.LastModificationTime = DateTime.Now;
            return SJson();
        }
        /// <summary>
        /// 修改实体
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        [HttpPut, Description("修改实体")]
        public async Task<TEntity> UpdateAsync(TEntity entity)
        {
            return await BaseService.GetBaseRepository().UpdateAsync(entity);
        }

        /// <summary>
        /// 根据主键Id删除实体
        /// </summary>
        /// <param name="id">实体主键</param>
        /// <returns></returns>
        [Description("异步删除实体")]
        public async Task<IActionResult> DeleteAsync(TPrimaryKey id)
        {
            return await BaseService.DeleteAsync(new InputIdDto<TPrimaryKey> { Id = id });
        }
        /// <summary>
        /// 批量删除实体
        /// </summary>
        /// <param name="entities">实体集</param>
        /// <returns></returns>
        [Description("批量删除数据")]
        public async Task<IActionResult> BulkDeleteAsync(List<TEntity> entities)
        {
            return await BaseService.BulkDeleteEntityAsync(entities);
        }
        /// <summary>
        /// 批量删除实体
        /// </summary>
        /// <param name="ids">实体主键集</param>
        /// <returns></returns>
        [Description("批量删除数据")]
        public async Task<IActionResult> BulkDeleteAsync(List<TPrimaryKey> ids)
        {
            return await BaseService.BulkDeleteAsync(ids);
        }

        #endregion

        #region 重复性验证 重新设计
        /// <summary>
        /// 单字段重复性验证
        /// </summary>
        /// <param name="field">单个字段选项</param>
        /// <returns></returns>
        [HttpPost]
        public virtual IActionResult CheckFieldUnique(FieldCheckOptionDto<TPrimaryKey> field)
        {
            return BaseService.CheckFieldUnique(field);
        }
        /// <summary>
        /// 多字段重复性验证，dxGrid在新建/编辑数据时 时时验证
        /// </summary>
        /// <param name="fields">多字段dto选项</param>
        /// <returns></returns>
        [HttpPost]
        public virtual IActionResult CheckFieldsUnique(List<FieldCheckOptionDto<TPrimaryKey>> fields)
        {
            return BaseService.CheckFieldsUnique(fields);
        }

        #endregion

        #region 根据前端Grid传递的values json字符串反序列化为当前实体对象

        protected TEntity GetValues<TEntity>()
        {
            var formData = Request.Form["values"];
            var entity = JsonConvert.DeserializeObject<TEntity>(formData);
            return entity;
        }

        protected TEntity GetValues<TEntity>(string valueString)
        {
            var entity = JsonConvert.DeserializeObject<TEntity>(valueString);
            return entity;
        }
        protected string GetValuesString()
        {
            var formData = Request.Form["values"].ToString();
            //formData = formData.Replace(" ", "");//去掉所有空格
            return formData.Trim();
        }


        protected string GetKeyString()
        {
            var formData = Request.Form["key"];
            return formData;
        }
        protected int GetKey()
        {
            var formData = GetKeyString();
            int.TryParse(formData, out var key);
            return key;
        }
        protected int GetId()
        {
            var value = Request.Form["id"];
            return string.IsNullOrWhiteSpace(value) ? 0 : Convert.ToInt32(value);
        }

        #endregion

    }

    public abstract class BaseEntityController<TEntity> : BaseEntityController<TEntity, int> where TEntity : BaseEntity
    {
        protected BaseEntityController(IBaseNetCoreAppService<TEntity> baseService) : base(baseService)
        {
        }
    }

}
